package cn.iocoder.yudao.module.reading.dal.mysql.banner;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.reading.controller.admin.banner.vo.BannerPageReqVO;
import cn.iocoder.yudao.module.reading.dal.dataobject.banner.BannerDO;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 横幅管理 Mapper
 *
 * @author 李晨
 */
@Mapper
public interface BannerMapper extends BaseMapperX<BannerDO> {

    /**
     * 查询有效的横幅列表，按排序权重倒序
     * 只返回状态为启用且在有效时间范围内的横幅
     *
     * @return 有效横幅列表
     */
    default List<BannerDO> selectActiveBanners() {
        LocalDateTime now = LocalDateTime.now();
        return selectList(new LambdaQueryWrapperX<BannerDO>()
                .eq(BannerDO::getStatus, true)
                .and(wrapper -> wrapper
                        .isNull(BannerDO::getStartTime)
                        .or()
                        .le(BannerDO::getStartTime, now)
                )
                .and(wrapper -> wrapper
                        .isNull(BannerDO::getEndTime)
                        .or()
                        .ge(BannerDO::getEndTime, now)
                )
                .orderByDesc(BannerDO::getSortOrder)
                .orderByDesc(BannerDO::getCreateTime));
    }

    /**
     * 查询有效的横幅列表，限制数量
     *
     * @param limit 限制数量
     * @return 有效横幅列表
     */
    default List<BannerDO> selectActiveBanners(Integer limit) {
        LocalDateTime now = LocalDateTime.now();
        return selectList(new LambdaQueryWrapperX<BannerDO>()
                .eq(BannerDO::getStatus, true)
                .and(wrapper -> wrapper
                        .isNull(BannerDO::getStartTime)
                        .or()
                        .le(BannerDO::getStartTime, now)
                )
                .and(wrapper -> wrapper
                        .isNull(BannerDO::getEndTime)
                        .or()
                        .ge(BannerDO::getEndTime, now)
                )
                .orderByDesc(BannerDO::getSortOrder)
                .orderByDesc(BannerDO::getCreateTime)
                .last(limit != null ? "LIMIT " + limit : ""));
    }

    /**
     * 根据标题查询横幅
     *
     * @param title 横幅标题
     * @return 横幅
     */
    default BannerDO selectByTitle(String title) {
        return selectOne(BannerDO::getTitle, title);
    }

    /**
     * 分页查询横幅
     *
     * @param reqVO 查询条件
     * @return 分页结果
     */
    default PageResult<BannerDO> selectPage(BannerPageReqVO reqVO) {
        return selectPage(reqVO, new LambdaQueryWrapperX<BannerDO>()
                .likeIfPresent(BannerDO::getTitle, reqVO.getTitle())
                .eqIfPresent(BannerDO::getStatus, reqVO.getStatus())
                .geIfPresent(BannerDO::getCreateTime, reqVO.getStartTime())
                .leIfPresent(BannerDO::getCreateTime, reqVO.getEndTime())
                .orderByDesc(BannerDO::getSortOrder)
                .orderByDesc(BannerDO::getCreateTime));
    }

    /**
     * 更新横幅点击次数
     *
     * @param id 横幅ID
     */
    default void incrementClickCount(Long id) {
        update(null, new LambdaUpdateWrapper<BannerDO>()
                .eq(BannerDO::getId, id)
                .setSql("click_count = click_count + 1"));
    }

    /**
     * 批量更新横幅状态
     *
     * @param ids 横幅ID列表
     * @param status 状态
     */
    default void updateStatusBatch(List<Long> ids, Boolean status) {
        update(null, new LambdaUpdateWrapper<BannerDO>()
                .in(BannerDO::getId, ids)
                .set(BannerDO::getStatus, status));
    }

}
